import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withRouter, matchPath } from 'react-router';
import { Route, Switch } from 'react-router-dom';
import { NProgress } from '@tanem/react-nprogress';
import { CSSTransition } from 'react-transition-group';
import { ViewerbaseDragDropContext } from '@ohif/ui';
import { Result } from 'antd';
import ErrorBoundaryDialog from './components/ErrorBoundaryDialog';
import * as RoutesUtil from './routes/routesUtil';
import { Bar, Container } from './components/LoadingBar';

import 'antd/dist/antd.dark.css';
import './variables.css';
import './theme-tide.css';
import './StandaloneViewer.css';
// Contexts
import AppContext from './context/AppContext';

class StandaloneViewer extends Component {
  static contextType = AppContext;
  state = {
    isLoading: false,
  };

  static propTypes = {
    history: PropTypes.object.isRequired,
    setContext: PropTypes.func,
    location: PropTypes.object,
  };

  componentDidMount() {
    this.unlisten = this.props.history.listen((location, action) => {
      if (this.props.setContext) {
        this.props.setContext(window.location.pathname);
      }
    });
  }

  componentWillUnmount() {
    this.unlisten();
  }

  render() {
    const {
      appConfig = {}
    } = this.context;

    /**
     * Note: this approach for routing is caused by the conflict between
     * react-transition-group and react-router's <Switch> component.
     *
     * See http://reactcommunity.org/react-transition-group/with-react-router/
     */
    const routes = RoutesUtil.getRoutes(appConfig);

    const currentPath = this.props.location.pathname;
    const noMatchingRoutes = !routes.find(r =>
      matchPath(currentPath, {
        path: r.path,
        exact: true,
      })
    );

    return (
      <>
        <NProgress isAnimating={this.state.isLoading}>
          {({ isFinished, progress, animationDuration }) => (
            <Container
              isFinished={isFinished}
              animationDuration={animationDuration}
            >
              <Bar progress={progress} animationDuration={animationDuration} />
            </Container>
          )}
        </NProgress>
        <Switch>
          <Route exact path="/silent-refresh.html" onEnter={RoutesUtil.reload} />
          <Route exact path="/logout-redirect.html" onEnter={RoutesUtil.reload} />
          {!noMatchingRoutes &&
            routes.map(({ path, Component }) => (
              <Route key={path} path={path}>
                {({ match }) => (
                  <CSSTransition
                    in={match !== null}
                    timeout={300}
                    classNames="fade"
                    unmountOnExit
                    onEnter={() => {
                      this.setState({
                        isLoading: true,
                      });
                    }}
                    onEntered={() => {
                      this.setState({
                        isLoading: false,
                      });
                    }}
                  >
                    {match === null ? (
                      <></>
                    ) : (
                      <ErrorBoundaryDialog context={match.url}>
                        <Component match={match} location={this.props.location} />
                      </ErrorBoundaryDialog>
                    )}
                  </CSSTransition>
                )}
              </Route>
            ))
          }
        </Switch>
        {noMatchingRoutes && <Result status="404" title="Sorry, the page you visited does not exist." />}
      </>
    );
  }
}

export default ViewerbaseDragDropContext(
  withRouter(StandaloneViewer)
);
